namespace Yaaf.Wp7.AdvancedExplorer.ViewModels
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.IO;
    using System.ServiceModel;
    using System.Threading;
    using System.Windows;
    using System.Windows.Media.Imaging;
    using System.Windows.Threading;

    using Yaaf.Wp7.AdvancedExplorer.FileExchangeService;
    using Yaaf.Wp7.AdvancedExplorer.Resources;
    using Yaaf.Wp7.AdvancedExplorer.Uploading;

    public class RemoteConnectionViewModel : IPivotView
    {
        public string Header
        {
            get
            {
                return "remote";
            }
        }

        private readonly MainViewModel mainView;

        private string currentPath;

        public string CurrentPath
        {
            get
            {
                return this.currentPath;
            }
            set
            {
                if (this.currentPath != value)
                {
                    this.currentPath = value;
                    ThreadPool.QueueUserWorkItem(StartRefreshing);
                    this.NotifyPropertyChanged("CurrentPath");
                }
            }
        }

        /// <summary>
        /// A collection for ItemViewModel objects.
        /// </summary>
        public ObservableCollection<RemoteFileEntryViewModel> FileEntries { get; private set; }

        public RemoteConnectionViewModel( MainViewModel mainView)
        {
            this.FileEntries = new ObservableCollection<RemoteFileEntryViewModel>();
            this.mainView = mainView;
            this.currentPath = "";
        }

        private bool isListing = false;
        public bool IsListing
        {
            get
            {
                return isListing;
            }
        }
        
        private bool stopListing;

        private object workingSync = new object();

        public void LoadData()
        {
            this.Refresh();
        }

        public void Refresh()
        {
            ThreadPool.QueueUserWorkItem(StartRefreshing);
        }

        private void StartRefreshing(object state)
        {
            if (isListing)
            {
                stopListing = false;
            }

            lock (workingSync)
            {
                if (isListing)
                {
                    throw new InvalidOperationException("Should not happen!");
                }

                isListing = true;

                mainView.Invoke(() => {
                    this.NotifyPropertyChanged("IsListing");
                    this.FileEntries.Clear();
                });
                try
                {
                    foreach (var remoteFile in ServiceConnection.EnumerateEntries(CurrentPath))
                    {
                        if (stopListing)
                        {
                            isListing = false;
                            return;
                        }

                        var remoteView = new RemoteFileEntryViewModel(CurrentPath, remoteFile);
                        this.mainView.Invoke(() => this.FileEntries.Add(remoteView));
                    }
                }
                catch (EndpointNotFoundException)
                {
                    this.mainView.Invoke(() =>
                        {
                            this.FileEntries.Clear();
                            this.FileEntries.Add(new RemoteFileEntryViewModel("", new FileElement(){IsFile = true, Name = AppResources.RemoteEndpointNotFound}));
                        });
                }
                catch (Exception e)
                {
                    mainView.Invoke(() =>
                        { MessageBox.Show(AppResources.Error2 + e, AppResources.Error, MessageBoxButton.OK); });
                }
                finally
                {
                    isListing = false;
                }
               

            }

            mainView.Invoke(() =>
            {
                this.NotifyPropertyChanged("IsListing");
            });
        }


        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public void AddTasks(string currentPath, FileElement element, Yaaf.WP7.NativeAccess.IO.DirectoryInfo targetDir)
        {
            var fullPath = currentPath + "\\" + element.Name;
            if (element.IsFile)
            {
                targetDir.Create();
                mainView.AddTasks(
                    ServiceConnection.DownloadTask(
                        () =>Yaaf.WP7.NativeAccess.IO.File.Open(targetDir.FullName + "\\" + element.Name, FileMode.Create, FileAccess.Write), fullPath));

            }
            else
            {
                try
                {
                    foreach (var entry in ServiceConnection.EnumerateEntries(fullPath))
                    {
                        this.AddTasks(fullPath, entry, new WP7.NativeAccess.IO.DirectoryInfo(targetDir.FullName + "\\" + element.Name));
                    }
                }
                catch (Exception e)
                {
                    mainView.Invoke(() => MessageBox.Show(AppResources.Error2 + e, AppResources.Error, MessageBoxButton.OK));
                }
                
            }
        }
    }

    public class RemoteFileEntryViewModel : INotifyPropertyChanged
    {
        private readonly string currentPath;

        private readonly FileElement remoteFile;


        public string ElementName
        {
            get
            {
                return this.remoteFile.Name;
            }
        }

        public RemoteFileEntryViewModel(string currentPath, FileElement remoteFile)
        {
            this.currentPath = currentPath;
            this.remoteFile = remoteFile;
        }

        private bool isSelected;

        public bool IsSelected
        {
            get
            {
                return this.isSelected;
            }
            set
            {
                this.isSelected = value;
                this.NotifyPropertyChanged("IsSelected");
            }
        }

        public BitmapImage Icon
        {
            get
            {
                if (!remoteFile.IsFile)
                {
                    return IconStore.IconFolder;
                }

                return IconStore.GetImage(Path.GetExtension(remoteFile.Name));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public FileElement Element
        {
            get
            {
                return remoteFile;
            }
        }

        public void StartDownloadTo(WP7.NativeAccess.IO.DirectoryInfo currentDir)
        {
            ThreadPool.QueueUserWorkItem((s) => App.ViewModel.RemoteConnection.AddTasks(currentPath, Element, currentDir));
        }
    }
}